
#include "liveMedia.hh"
#include "GroupsockHelper.hh"
#include "BasicUsageEnvironment.hh"
#include <opencv/cv.h>
#include <opencv2/core/types_c.h>
#include <opencv2/core/gpumat.hpp>
#include <opencv2/core/operations.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/contrib/contrib.hpp>
#include "opencv2/video/background_segm.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <stdio.h>
#include <sys/time.h>  
#include <unistd.h>   
#include <string.h>
#include <opencv/cxcore.h>
#include <opencv/highgui.h>
#include <stdlib.h>
#include <libxml/parser.h>
#include <pthread.h>
#include <exception>
#include <iostream>
using namespace std;
using namespace cv; 
const double MHI_DURATION = 0.5;
const double MAX_TIME_DELTA = 0.5;
const double MIN_TIME_DELTA = 0.05;
const int N = 3;
const double BINARYTHRES=30;
const int RECT_MAX_AERA = 100;//面积小于RECT_MAX_AERA的rect将忽略
const int interval = 1;
int cms_fd = -1;
HashTable * videoSession = HashTable::create(0); //用来存储VIDEOSESSION的Hash表

#define MAXDATASIZE 4096
#define CMS_SERVER_IP "127.0.0.1"
#define CMS_SERVER_PORT 8000
#define MAXCONN_NUM 10
int numbytes,sock_fd;
struct sockaddr_in server_addr; 
char buf[MAXDATASIZE]; 
pthread_mutex_t mutex;  // sock_fd
const char * registermsg = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
                            <Envelope type=\"vregister\"> \
                            </Envelope>";

struct vsession{
    char mac[100];
    char cfd[10];
    char rtspurl[200];
    int startcol;
    int startrow;
    int endcol;
    int endrow; 
};

class VideoUnderstanding{
public:
    Point *ptStart,*ptEnd;
    IplImage **buf=0,*mhi =0, *motion=0;
    CvPoint pt[4];
    CvCapture *capture;
    int last =  0;
    char rtspurl[200];
    char mac[100];
    char cfd[10];
    pthread_t rpt;
    struct timeval start,end;
    int flag = 0;
public:
    VideoUnderstanding(char * rtspurl,int psc,int psr,int per,int pec, char * vsmac, char * vscfd);
    ~VideoUnderstanding();
    int PointAtLineLeftRight(Point ptStart, Point ptEnd, Point ptTest);
    bool IsTwoLineIntersect(Point ptLine1Start, Point ptLine1End, Point ptLine2Start, Point ptLine2End);
    bool IsLineIntersectRect(Point ptStart, Point ptEnd, Rect rect);
    void update_mhi(IplImage *img, IplImage *dst, int diff_threshold);
    int run();
    int stop();
    int sendwarningmessage(const char * type);
    int sendstartreply(int flag);
};


void *run_thread(void * lw);
int mutex_send(char * buffer);
int DecodeXml(char * buffer);
struct vsession vs;
VideoUnderstanding * lwt;
xmlNodePtr tmpNode;


VideoUnderstanding::VideoUnderstanding(char * url,int psc,int psr,int pec,int per, char * vsmac, char * vscfd){
    strcpy(rtspurl, url);
    //tflag = time();
    ptStart = new Point(psc,psr);
    ptEnd = new Point(pec,per);
    flag = 0;
    strcpy(mac, vsmac);
    strcpy(cfd, vscfd);
}

VideoUnderstanding::~VideoUnderstanding(){
    delete ptStart;
    delete ptEnd;
}

int VideoUnderstanding::PointAtLineLeftRight(Point Start, Point End, Point Test)
{
    Start.x -= Test.x;
    Start.y -= Test.y;
    End.x -= Test.x;
    End.y -= Test.y;
    int nRet = Start.x * End.y - Start.y * End.x;
    if (nRet == 0)
        return 0;
    else if (nRet > 0)
        return 1;
    else if (nRet < 0)
        return -1;
    return 0;
}

bool VideoUnderstanding::IsTwoLineIntersect(Point ptLine1Start, Point ptLine1End, Point ptLine2Start, Point ptLine2End)
{
    int nLine1Start = PointAtLineLeftRight(ptLine2Start, ptLine2End, ptLine1Start);
    int nLine1End = PointAtLineLeftRight(ptLine2Start, ptLine2End, ptLine1End);
    if (nLine1Start * nLine1End > 0)
        return FALSE;
    int nLine2Start = PointAtLineLeftRight(ptLine1Start, ptLine1End, ptLine2Start);
    int nLine2End = PointAtLineLeftRight(ptLine1Start, ptLine1End, ptLine2End);
    if (nLine2Start * nLine2End > 0)
        return FALSE;
    return TRUE;
}

bool VideoUnderstanding::IsLineIntersectRect(Point Start, Point End, Rect rect)
{
    // Two point both are in rect
    if (rect.contains(Start) && rect.contains(End))
        return TRUE;
    // One point is in rect, another not.
    if (rect.contains(Start) && !rect.contains(End))
        return TRUE;
    if (!rect.contains(Start) && rect.contains(End))
        return TRUE;
    // Two point both aren't in rect
    if (IsTwoLineIntersect(Start, End, Point(rect.x, rect.y), Point(rect.x+rect.width, rect.y)))
        return TRUE;
    if (IsTwoLineIntersect(Start, End, Point(rect.x+rect.width, rect.y), Point(rect.x+rect.width, rect.y-rect.height)))
        return TRUE;
    if (IsTwoLineIntersect(Start, End, Point(rect.x+rect.width, rect.y-rect.height),Point(rect.x, rect.y-rect.height)))
        return TRUE;
    if (IsTwoLineIntersect(Start, End, Point(rect.x, rect.y-rect.height),Point(rect.x, rect.y)))
        return TRUE;
    return FALSE;
}

void  VideoUnderstanding::update_mhi( IplImage* img, IplImage* dst, int diff_threshold )
{
    double timestamp = clock()/100.; // get current time in seconds
    CvSize size = cvSize(img->width,img->height); // get current frame size
    int i, idx1, idx2;
    IplImage* silh;
    IplImage *img1;
    IplImage* pyr = cvCreateImage( cvSize((size.width & -2)/2, (size.height & -2)/2), 8, 1 );
    CvMemStorage *stor;
    CvSeq *cont, *result;

    if( !mhi || mhi->width != size.width || mhi->height != size.height ) {
        if( buf == 0 ) {
            buf = (IplImage**)malloc(N*sizeof(buf[0]));
            memset( buf, 0, N*sizeof(buf[0]));
        }
        for( i = 0; i < N; i++ ) {
            cvReleaseImage( &buf[i] );
            buf[i] = cvCreateImage( size, IPL_DEPTH_8U, 1 );
            cvZero( buf[i] );
        }
        cvReleaseImage( &mhi );
        mhi = cvCreateImage( size, IPL_DEPTH_32F, 1 );
        cvZero( mhi ); // clear MHI at the beginning
    } // end of if(mhi)

    cvCvtColor( img, buf[last], CV_BGR2GRAY ); // convert frame to grayscale
    idx1 = last;
    idx2 = (last + 1) % N; // index of (last - (N-1))th frame 
    last = idx2;
    // 做帧差
    silh = buf[idx2];
    cvAbsDiff( buf[idx1], buf[idx2], silh ); // get difference between frames 
    // 对差图像做二值化
    cvThreshold( silh, silh, BINARYTHRES, 255, CV_THRESH_BINARY ); // and threshold it
    cvUpdateMotionHistory( silh, mhi, timestamp, MHI_DURATION ); // update MHI
    cvCvtScale( mhi, dst, 255./MHI_DURATION, 
      (MHI_DURATION - timestamp)*255./MHI_DURATION );    
    cvCvtScale( mhi, dst, 255./MHI_DURATION, 0 );    
    // 中值滤波，消除小的噪声
    cvSmooth( dst, dst, CV_MEDIAN, 3, 0, 0, 0 );
    // 向下采样，去掉噪声
    cvPyrDown( dst, pyr, 7 );
    cvDilate( pyr, pyr, 0, 1 );  // 做膨胀操作，消除目标的不连续空洞
    cvPyrUp( pyr, dst, 7 );
    //
    // 下面的程序段用来找到轮廓
    //
    // Create dynamic structure and sequence.
    stor = cvCreateMemStorage(0);
    cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor);
    result = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor);//jm+
    // 找到所有轮廓
    cvFindContours( dst, stor, &cont, sizeof(CvContour),CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

    //cvCvtColor(img, img1, CV_BGR2GRAY);
    int num[16];
    for (int i = 0; i < 16; i++)
        num[i] = 0;
    for (int i = 1; i <= img->height;i++)
        for (int j = 1; j <= img->width; j++)
        {
            int x = CV_IMAGE_ELEM(img, uchar, i, j);
            x = x/16;
            num[x]++;
        }

    int flag = 0;
    int tmp = img->height * img->width / 2;
    for (int i = 0; i < 16; i++)
    {
        if (num[i] >= tmp)
        {
            flag = 1;
            break;
        }
    }
    for(;cont;cont = cont->h_next)
    {
        Rect r = ((CvContour*)cont)->rect;
        // 直接使用CONTOUR中的矩形来画轮廓
        //面积小于RECT_MAX_AERA的rect将忽略
        if (r.height * r.width > RECT_MAX_AERA){
            cvRectangle( img, cvPoint(r.x,r.y), cvPoint(r.x + r.width, r.y + r.height),CV_RGB(255,0,0), 1, CV_AA,0);
            if(IsLineIntersectRect(*ptStart,*ptEnd,r))//如果有面积大的rect和线相交则输出警报
                gettimeofday(&end,NULL);
                //printf("end-sec:%d\n",end.tv_sec);
                //printf("%d",end.tv_sec - start.tv_sec);
                if(end.tv_sec - start.tv_sec >= interval){
                
                    if (flag == 1)
                    {
                        printf("WARNING:Somebody shelter from the screen!\n");
                        sendwarningmessage("shelter");
                    }
                    
                    printf("WARNING:Somebody cross the line!!\n");
                    sendwarningmessage("cross");
                    gettimeofday(&start,NULL);
                    //printf("start-sec:%d\n",start.tv_sec);
                }
          }
    }
    cvReleaseMemStorage(&stor);
    cvReleaseImage( &pyr );
}

int VideoUnderstanding::run()
{
       int lthread = pthread_create(&rpt, NULL, run_thread, this);
        if(lthread < 0){
            printf("run_thread create failed!\n");
            return -1;
         }
         return 0;
}

int VideoUnderstanding::stop(){
    cvReleaseCapture(&capture);
    pthread_cancel(rpt);
    return 0;
}

int VideoUnderstanding::sendwarningmessage(const char * type){
    xmlDocPtr doc = NULL;
    xmlNodePtr root_node = NULL, profile = NULL, rts= NULL, typ= NULL, wti = NULL, trts = NULL,ttyp = NULL, twti = NULL,xmac = NULL, xcfd = NULL, tmac = NULL, tcfd = NULL;
    doc = xmlNewDoc(BAD_CAST "1.0");
    root_node = xmlNewNode(NULL, BAD_CAST "Envelope");
    xmlNewProp(root_node, BAD_CAST "type", BAD_CAST "warning");
    xmlDocSetRootElement(doc, root_node);
    profile = xmlNewNode(NULL, BAD_CAST "profile");
    rts=xmlNewNode( NULL, BAD_CAST "rtspuri");
    trts = xmlNewText(BAD_CAST rtspurl);
    xmac=xmlNewNode( NULL, BAD_CAST "mac");
    xcfd=xmlNewNode( NULL, BAD_CAST "cfd");
    tmac =  xmlNewText(BAD_CAST mac);
    tcfd =  xmlNewText(BAD_CAST cfd);
    typ = xmlNewNode(NULL, BAD_CAST "type");
    if( strcmp(type,"shelter") ==0 ){
          ttyp = xmlNewText(BAD_CAST"shelter");
    }else if( strcmp(type, "cross") == 0 ){
         ttyp = xmlNewText(BAD_CAST"cross");
    }else{
        ttyp = xmlNewText(BAD_CAST"unknown");
    }
    wti = xmlNewNode(NULL, BAD_CAST "time");
    time_t timep;
    time (&timep);
    twti = xmlNewText(BAD_CAST ctime(&timep));
    xmlAddChild(xmac,tmac);
    xmlAddChild(xcfd,tcfd);
    xmlAddChild(rts, trts);
    xmlAddChild(typ, ttyp);
    xmlAddChild(wti, twti);
    xmlAddChild(profile, xmac);
    xmlAddChild(profile, xcfd);
    xmlAddChild(profile, rts);
    xmlAddChild(profile, typ);
    xmlAddChild(profile, wti);
    xmlAddChild(root_node, profile);
    xmlChar *xml_buff;
    int size;
    xmlDocDumpMemory(doc,&xml_buff,&size);
    //xmlDocDumpFormatMemory(doc, &xml_buff, &size, 1);
    if(mutex_send((char *)xml_buff) >=0){
        xmlFreeDoc(doc);
        xmlCleanupParser();
        return 0;
    }else{
        xmlFreeDoc(doc);
        xmlCleanupParser();
        return -1;
    }

}



int VideoUnderstanding::sendstartreply(int flag){
    xmlDocPtr doc = NULL;
    xmlNodePtr root_node = NULL, profile = NULL, rts= NULL,action = NULL, xmac = NULL, xcfd = NULL, trts = NULL,taction = NULL, tmac = NULL, tcfd = NULL;
    doc = xmlNewDoc(BAD_CAST "1.0");
    root_node = xmlNewNode(NULL, BAD_CAST "Envelope");
    xmlNewProp(root_node, BAD_CAST "type", BAD_CAST "r_startdeal");
    xmlDocSetRootElement(doc, root_node);
    profile = xmlNewNode(NULL, BAD_CAST "profile");
    rts=xmlNewNode( NULL, BAD_CAST "rtspuri");
    xmac=xmlNewNode( NULL, BAD_CAST "mac");
    xcfd=xmlNewNode( NULL, BAD_CAST "cfd");
    trts = xmlNewText(BAD_CAST rtspurl);
    tmac =  xmlNewText(BAD_CAST mac);
    tcfd =  xmlNewText(BAD_CAST cfd);
    action = xmlNewNode(NULL, BAD_CAST "action");
    if( flag >0 ){
         taction = xmlNewText(BAD_CAST"success");
    }else if( flag < 0 ){
         taction = xmlNewText(BAD_CAST"fail");
    }else{
        taction = xmlNewText(BAD_CAST"exception");
    }
    xmlAddChild(rts, trts);
    xmlAddChild(xmac,tmac);
    xmlAddChild(xcfd,tcfd);
    xmlAddChild(action, taction);
    xmlAddChild(profile, xmac);
    xmlAddChild(profile, xcfd);
    xmlAddChild(profile, rts);
    xmlAddChild(profile, action);
    xmlAddChild(root_node, profile);
    xmlChar *xml_buff;
    int size;
    xmlDocDumpMemory(doc,&xml_buff,&size);
    if( mutex_send((char *)xml_buff) >= 0){
        xmlFreeDoc(doc);
        xmlCleanupParser();
        return 0;
    }else{
        xmlFreeDoc(doc);
        xmlCleanupParser();
        return -1;
    }
}


void *run_thread(void * lw){

        ((VideoUnderstanding*)lw)->capture = cvCreateFileCapture( ((VideoUnderstanding*)lw)->rtspurl);
        if( ((VideoUnderstanding*)lw)->capture == NULL ){
                printf("ERROR: Connection failed...\n");
                ((VideoUnderstanding*)lw)->sendstartreply(-1);
                pthread_exit(0);
        }else{
                ((VideoUnderstanding*)lw)->sendstartreply(1);
                videoSession->Add(((VideoUnderstanding*)lw)->rtspurl, (void *)lw);
        }
        try{
                if(((VideoUnderstanding*)lw)->capture ){
                        //cvNamedWindow( "Motion", 1 );
                        gettimeofday(& ((VideoUnderstanding*)lw)->start,NULL);
                        for(;;)
                        {
                                IplImage* image;
                                if( !cvGrabFrame( ((VideoUnderstanding*)lw)->capture ))  break;
                                image=cvQueryFrame( ((VideoUnderstanding*)lw)->capture );//用此句不花屏
                                image->origin=0;
                                if( image )
                                {
                                        if( ! ((VideoUnderstanding*)lw)->motion )
                                        {
                                                ((VideoUnderstanding*)lw)->motion = cvCreateImage( cvSize(image->width,image->height), 8, 1 );
                                                cvZero(((VideoUnderstanding*)lw)->motion );
                                                ((VideoUnderstanding*)lw)->motion->origin = image->origin;
                                        }
                                }
                                ((VideoUnderstanding*)lw)->update_mhi( image,  ((VideoUnderstanding*)lw)->motion, 60 );
                                //cvLine( image,* ((VideoUnderstanding*)lw)->ptStart,* ((VideoUnderstanding*)lw)->ptEnd,Scalar(255,0,0));   //画出警戒线
                                //cvShowImage( "Motion", image );
                                if( cvWaitKey(10) >= 0 ) break;
                        }
                        //cvReleaseCapture( & ((VideoUnderstanding*)lw)->capture );
                        //cvDestroyWindow( "Motion" );
                }
        }catch(exception &e){
                //exception while running
                printf("ERROR: Exception %s \n",e.what());
                ((VideoUnderstanding*)lw)->sendstartreply(0);
                videoSession->Remove(((VideoUnderstanding*)lw)->rtspurl);
        }
        pthread_exit(0);
}

int main(){
        pthread_mutex_init(&mutex,NULL);
        printf("INFO:VideoServer  started...\n");
        if ((sock_fd = socket ( AF_INET , SOCK_STREAM , 0)) == - 1) { 
                perror ("ERROR:Socket error\n"); 
                return -1;
        } 
            
        memset ( &server_addr, 0, sizeof(struct sockaddr)); 
        server_addr.sin_family = AF_INET; 
        server_addr.sin_port = htons (CMS_SERVER_PORT); 
        server_addr.sin_addr.s_addr = inet_addr(CMS_SERVER_IP); 
        if ( connect ( sock_fd, ( struct sockaddr * ) & server_addr, sizeof( struct sockaddr ) ) == -1) { 
                perror ("ERROR:Cannot connect to a CMSServer...\n"); 
                return -1;
        }
        if ( send ( sock_fd, registermsg , strlen(registermsg), 0) == - 1) { 
                perror ( "ERROR:Send error\n" ); 
        }

        fd_set fdsr;
        int ret;
        struct timeval tv;
        tv.tv_sec = 30;
        tv.tv_usec = 0;

        while(1){
                FD_ZERO(&fdsr);
                FD_SET(sock_fd, &fdsr);
                //printf("1---lock...\n");
                if(pthread_mutex_lock(&mutex)!=0){
                        printf("ERROR:Thread lock failed!\n"); 
                        continue;
                }
                ret = select(sock_fd + 1, &fdsr, NULL, NULL, &tv);
                pthread_mutex_unlock(&mutex);
                //printf("1---unlock...\n");

                if (ret < 0) {
                    perror("ERROR:Select...\n");
                    continue;
                } 
                if (ret == 0) {
                        sleep(0.1);
                        continue;
                }
                if (FD_ISSET(sock_fd, &fdsr)) {
                        //printf("2---lock...\n");
                        if(pthread_mutex_lock(&mutex)!=0){
                                printf("ERROR:Thread lock failed!\n"); 
                                continue;
                        }
                        ret = recv(sock_fd, buf, MAXDATASIZE, 0);
                        if (ret <= 0) { 
                                FD_CLR(sock_fd, &fdsr);
                                pthread_mutex_unlock(&mutex);
                                break;
                        } else {        // receive data
                                pthread_mutex_unlock(&mutex);
                                buf[ret] = '\0';
                                DecodeXml(buf);
                        }
                        //printf("2---unlock...\n");
                }
        }
        printf("ERROR:CMSServer is down, please restart it ...\n");
        close ( sock_fd); 
}


int DecodeXml(char * buffer){
    xmlDocPtr doc = xmlParseMemory(buffer,strlen(buffer));
    if (doc == NULL){
        return -1;
    }
    xmlNodePtr curNode = xmlDocGetRootElement(doc); //get root element
    if (curNode == NULL){
        xmlFreeDoc(doc);
        return -2;
    }
    if (xmlStrcmp(curNode->name, BAD_CAST "Envelope")){  //匹配Envelope
        xmlFreeDoc(doc);
        return -3;
    }
    if (xmlHasProp(curNode,BAD_CAST "type")){
        xmlChar * szAttr = xmlGetProp(curNode,BAD_CAST "type");
        //cout <<"XMLDecoded:" << szAttr << endl;

        if(!xmlStrcmp(szAttr,BAD_CAST "r_vregister")){  //匹配cmsregister
            cms_fd = sock_fd;
            cout << "INFO:Videoserver registered to a CMSServer...\n"<<endl;
        }

        if(cms_fd != sock_fd){  
            cout << "WARNING:got a unregistered message..." <<endl;
        }else{

            if(!xmlStrcmp(szAttr,BAD_CAST "startdeal")){  //匹配startstorage
                xmlSetProp(curNode, (const xmlChar*)"type", (const xmlChar*)"r_startdeal"); 
                xmlNodePtr sNode = curNode->xmlChildrenNode;
                while (sNode != NULL){
                    if(!xmlStrcmp(sNode->name,BAD_CAST "profile")){
                        xmlNodePtr cNode = sNode->xmlChildrenNode;
                        //cout << sNode->name <<endl;
                        while(cNode != NULL){
                            if (!xmlStrcmp(cNode->name,BAD_CAST "rtspuri")){
                                strcpy(vs.rtspurl ,(char *) xmlNodeGetContent(cNode));
                                cout <<"INFO:Start deal \""<<xmlNodeGetContent(cNode) <<"\""<<endl;
                                tmpNode = cNode->next;
                            }else if(!xmlStrcmp(cNode->name,BAD_CAST "mac")){
                                    strcpy(vs.mac ,(char *) xmlNodeGetContent(cNode));
                                    tmpNode = cNode->next;
                            }else if(!xmlStrcmp(cNode->name,BAD_CAST "cfd")){
                                    strcpy(vs.cfd ,(char *) xmlNodeGetContent(cNode));
                                    tmpNode = cNode->next;
                            }else{
                                if(!xmlStrcmp(cNode->name,BAD_CAST "startcol")){
                                    vs.startcol =  atoi((char *)xmlNodeGetContent(cNode));
                                    //cout <<"\t"<< cNode->name << " : "<<xmlNodeGetContent(cNode) <<endl;
                                }
                                if(!xmlStrcmp(cNode->name,BAD_CAST "startrow")){
                                    vs.startrow =  atoi((char *)xmlNodeGetContent(cNode));
                                    //cout <<"\t"<< cNode->name << " : "<<xmlNodeGetContent(cNode) <<endl;
                                }
                                if(!xmlStrcmp(cNode->name,BAD_CAST "endcol")){
                                    vs.endcol =  atoi((char *)xmlNodeGetContent(cNode));
                                    //cout <<"\t"<< cNode->name << " : "<<xmlNodeGetContent(cNode) <<endl;
                                }
                                if(!xmlStrcmp(cNode->name,BAD_CAST "endrow")){
                                    vs.endrow =  atoi((char *)xmlNodeGetContent(cNode));
                                    //cout <<"\t"<< cNode->name << " : "<<xmlNodeGetContent(cNode) <<endl;
                                }
                                tmpNode = cNode->next;
                                xmlUnlinkNode(cNode);
                                xmlFreeNode(cNode);
                            }
                            cNode = tmpNode;
                        }
                        if(!videoSession->Lookup(vs.rtspurl)){
                            VideoUnderstanding *lw = new  VideoUnderstanding(vs.rtspurl, vs.startcol, vs.startrow, vs.endcol, vs.endrow, vs.mac, vs.cfd);
                            //videoSession->Add(vs.rtspurl, (void *)lw);
                            lw->run();
                        }
                        xmlNewChild(sNode,NULL,(xmlChar *) "action",(xmlChar *) "success");
                        xmlFree(cNode);
                    }
                    sNode = sNode->next;
                }
                xmlFree(sNode);

                xmlChar *xml_buff;
                int size;
                xmlDocDumpMemory(doc,&xml_buff,&size);
                //mutex_send((char *)xml_buff);
            }
            if(!xmlStrcmp(szAttr,BAD_CAST "stopdeal")){  //匹配stopstorage
                xmlSetProp(curNode, (const xmlChar*)"type", (const xmlChar*)"r_stopdeal"); 
                xmlNodePtr sNode = curNode->xmlChildrenNode;
                while (sNode != NULL){
                    if(!xmlStrcmp(sNode->name,BAD_CAST "profile")){
                        xmlNodePtr cNode = sNode->xmlChildrenNode;
                        //cout << sNode->name <<endl;
                        while(cNode != NULL){
                            if (!xmlStrcmp(cNode->name,BAD_CAST "rtspuri")){
                                cout <<"INFO:Stop deal the \'"<<xmlNodeGetContent(cNode) <<"\""<<endl;
                                if(videoSession->Lookup((char *)xmlNodeGetContent(cNode))){
                                    lwt = (VideoUnderstanding *)videoSession->Lookup((char *)xmlNodeGetContent(cNode));
                                    lwt->stop();
                                    videoSession->Remove((char *)xmlNodeGetContent(cNode));
                                    delete lwt;
                                    lwt = NULL;
                                    xmlNewChild(sNode,NULL,(xmlChar *) "action",(xmlChar *) "success");
                                }else{
                                    xmlNewChild(sNode,NULL,(xmlChar *) "action",(xmlChar *) "fail");
                                }
                                //cout <<"\t"<< cNode->name << " : "<<xmlNodeGetContent(cNode) <<endl;
                            }
                            cNode = cNode->next;
                        }
                        xmlFree(cNode);
                    }
                    sNode = sNode->next;
                }
                xmlFree(sNode);
                xmlChar *xml_buff;
                int size;
                xmlDocDumpMemory(doc,&xml_buff,&size);
                mutex_send((char *)xml_buff);
            }
        }
        xmlFree(szAttr);
    }
    xmlFreeDoc(doc);
    return 0;
}


int mutex_send(char * buffer){
        //printf("Add lock...\n");
    if(pthread_mutex_lock(&mutex)!=0){
        printf("ERROR:Thread lock failed!\n"); 
        return -1;
    }
    if (send ( sock_fd, buffer , strlen(buffer), 0) == - 1 || sock_fd < 0) { 
        //printf("%d -- %s\n",sock_fd,buffer);
        perror ( "ERROR:Send error\n" );
        return -1;
    } 
    pthread_mutex_unlock(&mutex);
    //printf("unlock...\n");
    return 0;
}